<!--
 * @Description:
 * @Author: dh
 * @Date: 2021-09-15 10:32:03
 * @LastEditors: dh
 * @LastEditTime: 2024-09-18 14:51:37
-->
<!doctype html>
<html lang="en">

<head>
	<meta charset="UTF-8" />
	<meta http-equiv="X-UA-Compatible" content="IE=edge" />
	<meta name="viewport" content="width=device-width, initial-scale=1.0" />
	<title>1 原型链继承</title>
</head>
<!--
    核心： 将父类的实例作为子类的原型

    特点：
    1.非常纯粹的继承关系，实例是子类的实例，也是父类的实例
    2.父类新增原型方法/原型属性，子类都能访问到
    3.简单，易于实现

    缺点：
    1.无法实现继承多个父类
    2.来自原型对象的所有属性被所有实例共享
    3.创建子类实例时，无法向父类构造函数传参 （2、3两大致命缺陷）

    注意
    1.要想为子类新增属性和方法，必须要在new Animal()这样的语句之后执行，不能放到构造器中
 -->

<body>
	<script>
		function Animal(name) {
			this.name = name || 'Animal';
			this.sleep = function () {
				console.log(this.name + '正在睡觉！');
			};
			this.like = [];
		}
		Animal.prototype.eat = function (food) {
			console.log(this.name + '正在吃：' + food);
		};

		function Cat() { }
		Cat.prototype = new Animal();
		Cat.prototype.name = 'smallCat';

		var cat = new Cat();
		// console.log(cat.name); // smallCat
		// console.log(cat.eat('fish')); // smallCat 正在吃：fish
		// console.log(cat.sleep()); // smallCat正在睡觉！
		// console.log(cat instanceof Animal); //true
		// console.log(cat instanceof Cat); //true

		cat.like.push('fish');
		var cat2 = new Cat();
		// console.log(cat2.like);// ['fish'] 实例共享导致，致命缺陷

		// bug 因为子构造函数的原型被覆盖了, 所以现在子构造函数的原型的构造器属性已经不再指向Child，而是Parent。
		// console.log(Cat.prototype.constructor == Animal); // true
		// 修正
		Cat.prototype.constructor = Cat;
	</script>
</body>

</html>
